#include <scene.h>
#include <button.h>
#include <scene_manager.h>
#include <iostream>
#include <tilemap.h>
#include <tilemapgenerator.h>
#include <search/dfs.h>
#include <search/bfs.h>
#include <search/bfszx.h>
#include <search/dijkstra.h>
#include <list_selecter.h>
#include <thread>
#include <win32_utils.h>

class SceneGaming : public Scene{
private:
    SceneManager& sceneManager;
    std::unordered_map<std::string, Texture2D>& texture_blocks;
    Font* font;
    

    TileMap tilemap;
    TileMapGenerator mapgener{10,10,7};
    // btns
    TextButton btn_dfsbase{GetScreenWidth()-150*2,0,150,100,"dfs_base"};
    TextButton btn_bfsbase{GetScreenWidth()-150*2,100,150,100,"bfs_base"};
    TextButton btn_dijkstra{GetScreenWidth()-150*2,100*2,150,100,"dijkstra"};
    TextButton btn_Astar{GetScreenWidth()-150*2,100*3,150,100,"Astar"};

    TextButton btn_save{GetScreenWidth()-150, 0, 150, 100, "save"};
    TextButton btn_testgener{GetScreenWidth()-150, 100*1, 150, 100, "gener"};
    TextButton btn_fog {GetScreenWidth()-150, 100*2, 150, 100, "fog"};
    ListSelecter blockSelceter{1500,4,64,64,60};

    Texture2D texture_loading = LoadTexture("assets\\textures\\loding.png");
    std::vector<Rectangle> frames;
    int frame=0;
    float timeout=0;
public:
    SceneGaming(SceneManager& manager, std::unordered_map<std::string, Texture2D>& texture_blocks, Font* font) :sceneManager(manager),texture_blocks(texture_blocks),font(font) {
        // mapgener{10,10,0};
        // tilemap.load(mapgener.generate_base());
        btn_bfsbase.setOnClick([&](){
            tilemap.search(bfszx);
        });
        btn_dfsbase.setOnClick([&](){
            tilemap.search(dfs);
        });
        btn_dijkstra.setOnClick([&](){
            tilemap.search(dijkstra);
        });
        btn_Astar.setOnClick([&](){
            // TODO
            // tilemap.search(bfs);
        });

        btn_save.setOnClick([&](){
            tilemap.save("assets\\maze0.txt");
        });
        btn_testgener.setOnClick([&](){
            tilemap.load(mapgener.generate_base());
        });
        btn_fog.setOnClick([&](){
            tilemap.fogMode = ! tilemap.fogMode;
        });

        for(int j=0; j<3; j++)
            for(int i=0; i<4; i++)
                frames.push_back({(float)i*6,(float)j*6,6,6});

        blockSelceter.addActor(new ImageTextButton(texture_blocks["end"],"end"));
        blockSelceter.addActor(new ImageTextButton(texture_blocks["start"],"start"));
        blockSelceter.addActor(new ImageTextButton(texture_blocks["floor"],"floor"));
        blockSelceter.addActor(new ImageTextButton(texture_blocks["wall"],"wall"));
        blockSelceter.addActor(new ImageTextButton(texture_blocks["grass"],"grass"));
        blockSelceter.addActor(new ImageTextButton(texture_blocks["lava"],"lava"));
    };
    ~SceneGaming() {}

    void init() override {
        tilemap.initTextures(texture_blocks);
        tilemap.load("assets\\maze0.txt");
        tilemap.raycaster.setWalls(tilemap.walls);
    }

    void render(float dt) override {
        timeout += dt;
        if(timeout > 0.1)
        {
            frame++;
            timeout = 0;
        }
        frame = (frame)%12;
        if(!tilemap.getSearchFinished()) DrawTexturePro(texture_loading, frames[frame], {(float)GetScreenWidth()-150-100,0,100,100}, {0,0}, 0, WHITE);
        
        btn_bfsbase.render();
        btn_dfsbase.render();
        btn_dijkstra.render();
        btn_Astar.render();

        btn_save.render();
        btn_testgener.render();
        btn_fog.render();

        tilemap.render();

        // WinPressKey(0x5A);

        blockSelceter.render();

        if(IsMouseButtonDown(MOUSE_LEFT_BUTTON))
            tilemap.setBlock(GetMouseX()/48/tilemap.camera.zoom + tilemap.camera.target.x/48,
                GetMouseY()/48/tilemap.camera.zoom + tilemap.camera.target.y/48,
                blockSelceter.getActiveCustomIndex());

        if(IsMouseButtonDown(MOUSE_RIGHT_BUTTON))
            tilemap.setBlock(GetMouseX()/48/tilemap.camera.zoom + tilemap.camera.target.x/48,
                GetMouseY()/48/tilemap.camera.zoom + tilemap.camera.target.y/48,
                Blocks::floor);
        

        DrawTextureEx(*(blockSelceter.getActive()->getTexture()), {GetMouseX()-(float)24,GetMouseY()-(float)24}, 0, 3, WHITE);

        tilemap.drawInfo(2, GetScreenHeight()-32*9+4, 32, BLACK);
        tilemap.drawInfo(0, GetScreenHeight()-32*9+2, 32, GREEN);

        drawKey("Z","zoom-",1500,800);
        drawKey("x","zoom+",1500,860);
        drawKey("E","next path",1500, 920);
        
    }

    void drawKey(const char* key, const char* jie, int x, int y){
        DrawRectangleRoundedLinesEx({(float)x,(float)y,48,48},0.1,10,4,BLACK);
        int width;
        width = MeasureText(key,32);
        DrawText(key,x+24-width/2,y+8+4,32,BLACK);
        DrawText(jie,x+56+18,y+8,32,BLACK);
    }
};